#include "main.h"
#include "eeprom_fifo.h"
#include <avr/io.h>
#include <stdio.h>

UINT16	fifo_head;
UINT16	fifo_tail;

/*----------------- eeprom initialization -----------------------------------------------*/
void fifo_init()
{
  fifo_head = 0x0000;
  fifo_tail = 0x0000;
  
  EEPROM1_ENABLE();
  /* set write enable on eeprom 1*/
  eeprom_spi_write( EEPROM_WREN );
  EEPROM1_DISABLE();
  
  EEPROM1_ENABLE();
  /*/ write to status register */
  eeprom_spi_write( EEPROM_WRSR );
  eeprom_spi_write( 0 );		 
  EEPROM1_DISABLE();
  
  EEPROM1_ENABLE();
  eeprom_spi_write( EEPROM_RDSR );
  eeprom_spi_read();
  EEPROM1_DISABLE();
  
  return;
}

/*/----------------- eeprom write functions -----------------------------------------------*/
void fifo_push32( byte* b )
{
  byte c;
  byte len;
  len = 1;
  
  EEPROM1_ENABLE();
  eeprom_spi_write( EEPROM_WRITE );	/* sets to write*/
  eeprom_spi_write( fifo_head>>0x8 );	/*/ addres 8-14*/
  eeprom_spi_write( fifo_head );	/*/ addres 0-7*/
  
  c = *b;
  for(; len < 4; len++)
  {
    SPDR = c;
    c = *(b+len);
    loop_until_bit_is_set(SPSR, SPIF);
  }
  
  EEPROM1_DISABLE();
  
 /* return;*/
}

void fifo_put( byte* b, byte len)
{
  UINT16 head;
  byte c;
  byte i;
  i = 0x01;
  head = fifo_head;
  
  if( len == 0x0 )
    return;
    
  EEPROM1_ENABLE();
  eeprom_spi_write( EEPROM_WRITE );
  eeprom_spi_write( head>>0x8 );
  eeprom_spi_write( head );
  head += len;
  head &= (EEPROM_SIZE-0x1);
  fifo_head = head;
  
  c = *b;
  for(; i < len; i++)
  {
    SPDR = c;
    c = *(b + i);
    loop_until_bit_is_set(SPSR, SPIF);
  }
  
  EEPROM1_DISABLE();
  
  return;
}


/*/----------------- eeprom read functions -----------------------------------------------*/
byte fifo_pop( byte* b, byte len)
{
  UINT16 head, tail;
  byte c,/*d*/i;
  
  tail = fifo_tail;
  head = fifo_head;
  i = 0x00;
  
  if( ((head-tail)&(EEPROM_SIZE - 1)) < len )
    return 0x01;
  
  EEPROM1_ENABLE();
  eeprom_spi_write( EEPROM_READ );
  eeprom_spi_write( tail>>0x8 );
  eeprom_spi_write( tail );
  
  tail++;
  tail &= ( EEPROM_SIZE - 1 );
  fifo_tail = tail;
  
  /*d = 0xff;*/
  SPDR = 0xFF;
  for(;i < len; i++)
  {
    loop_until_bit_is_set(SPSR, SPIF); c = SPDR; SPDR = 0xFF; *(b+i) = c;
  }
  
  EEPROM1_DISABLE();
  
  return 0;
}

byte fifo_pop32b( byte* b)
{
  return fifo_pop( b, 0x04 );
}

UINT16	fifo_free(void)
{
	UINT16 i;
	
	if( fifo_tail < fifo_head )
	{
		i = EEPROM_SIZE - (fifo_head - fifo_tail);
	}
	else if( fifo_tail > fifo_head )
	{
		i = fifo_tail - fifo_head;
	}
	else
	{
		i = EEPROM_SIZE;
	}
	
	return i-1;
}

UINT16 fifo_buffer(void)
{
	UINT16 i;
	if( fifo_head > fifo_tail)
	{
		i = fifo_head - fifo_tail;
	}
	else if ( fifo_head < fifo_tail )
	{
		i = EEPROM_SIZE - ( fifo_tail - fifo_head );
	}
	else
	{
		i = 0x0000;
	}
	
	return i-1;
}

/*/----------------- eeprom spi functions -----------------------------------------------*/
void eeprom_spi_write( byte b )
{
  SPDR = b;
  loop_until_bit_is_set(SPSR, SPIF);
  
  return;
}

byte eeprom_spi_read(void)
{
  SPDR = 0xFF;
  loop_until_bit_is_set(SPSR, SPIF);
  
  return SPDR;
}